/**
 * @author        Nicolas Bottarini <nicolasbottarini@gmail.com>, 404 <http://www.proyecto404.com>
 * @version       $Rev: 3 $
 * @lastrevision  $Date: 2011-09-12 16:45:37 +0000 (Mon, 12 Sep 2011) $	 
 */
package com.proyecto404.core.mvc {
	import com.proyecto404.core.AssetInfo;
	import com.proyecto404.core.BaseObject;
	import com.proyecto404.core.Check;
	import com.proyecto404.core.collections.Dictionary;
	import com.proyecto404.core.exception.InvalidOperationException;
	import com.proyecto404.core.util.BitmapHelper;
	import com.proyecto404.core.util.ClassHelper;
	import com.proyecto404.core.util.FileHelper;
	import com.proyecto404.core.util.StringHelper;
	
	import flash.display.Bitmap;
	import flash.display.DisplayObject;
	import flash.display.MovieClip;
	import flash.media.Sound;
	import flash.system.ApplicationDomain;
	import flash.text.Font;
	
	import spark.utils.BitmapUtil;
	
	public class Library extends BaseObject {
		private var _sounds:Dictionary;
		private var _bitmaps:Dictionary;
		private var _swfs:Dictionary;
		private var _application:Application;
		
		public function Library(application:Application) {
			super();
			_sounds = new Dictionary();
			_bitmaps = new Dictionary();
			_swfs = new Dictionary();
			_application = application;
		}
		
		public function storeSwf(name:String, asset:DisplayObject):void {
			Check.argument.isNotNull(name, "name");
			Check.argument.isNotNull(asset, "asset");
			_swfs.add(name, asset);
		}
		
		public function storeSound(name:String, asset:Sound):void {
			Check.argument.isNotNull(name, "name");
			Check.argument.isNotNull(asset, "asset");
			_sounds.add(name, asset);
		}

		public function storeBitmap(name:String, asset:Bitmap):void {
			Check.argument.isNotNull(name, "name");
			Check.argument.isNotNull(asset, "asset");
			_bitmaps.add(name, asset.bitmapData);
		}

		public function removeSwf(name:String):void {
			Check.argument.isNotNull(name, "name");
			_swfs.removeKey(name);
		}
		
		public function removeSound(name:String):void {
			Check.argument.isNotNull(name, "name");
			_sounds.removeKey(name);
		}

		public function removeBitmap(name:String):void {
			Check.argument.isNotNull(name, "name");
			_bitmaps.removeKey(name);
		}

		public function containsSwf(name:String):Boolean {
			Check.argument.isNotNull(name, "name");
			return _swfs.containsKey(name);
		}
		
		public function containsSound(name:String):Boolean {
			Check.argument.isNotNull(name, "name");
			return _sounds.containsKey(name);
		}

		public function containsBitmap(name:String):Boolean {
			Check.argument.isNotNull(name, "name");
			return _bitmaps.containsKey(name);
		}

		public function getSwf(name:String):DisplayObject {
			Check.argument.isNotNull(name, "name");
			return _swfs.get(name); 
		}

		public function getSound(name:String):Sound {
			Check.argument.isNotNull(name, "name");
			return _sounds.get(name);
		}

		public function getBitmap(name:String):Bitmap {
			Check.argument.isNotNull(name, "name");
			return new Bitmap(_bitmaps.get(name));
		}
		
		public function getBitmapFromSwf(className:String, swfName:String = "library.swf"):Bitmap {
			Check.argument.isNotNull(className, "className");
			Check.argument.isNotNull(swfName, "swfName");
			if (!containsSwf(swfName)) {
				throw new InvalidOperationException("The library");
			}
			
			var swf:DisplayObject = getSwf(swfName);
			var BitmapClass:Class = swf.loaderInfo.applicationDomain.getDefinition(className) as Class;
			return new Bitmap(new BitmapClass(0,0));
		}

		public function getAssetFromSwf(className:String, swfName:String = "library.swf"):Object {
			Check.argument.isNotNull(className, "className");
			Check.argument.isNotNull(swfName, "swfName");
			if (!containsSwf(swfName)) {
				throw new InvalidOperationException("The library does not contains a definition for " + className + " in " + swfName + ". Remember to declare classes in declareRuntimeInstantiationClasses");
			}
			
			var swf:DisplayObject = getSwf(swfName);
			var AssetClass:Class = swf.loaderInfo.applicationDomain.getDefinition(className) as Class;
			return new AssetClass();
		}
		
		public function getMovieClipFromSwf(className:String, swfName:String = "library.swf"):MovieClip {
			return MovieClip(getAssetFromSwf(className, swfName));	
		}

		public function containsView(viewName:String):Boolean {
			return _application.viewFactory.containsView(viewName);
		}
		
		public function getView(viewName:String, model:* = null):View {
			return _application.viewFactory.createView(viewName, model);
		}

		public function getLayout(viewName:String):LayoutView {
			return _application.viewFactory.createLayout(viewName);
		}

		public function getSoundFromSwf(className:String, swfName:String = "library.swf"):Sound {
			return Sound(getAssetFromSwf(className, swfName));
		}
		
		public function getFontFromSwf(className:String, swfName:String = "library.swf"):Font {
			return Font(getAssetFromSwf(className, swfName));
		}
	}
}